package flextv.data.versions {

import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;

import flextv.core.logic.Logger;
import flextv.data.IPersistenceService;
import flextv.data.MockPersistenceService;
import flextv.data.PersistenceServiceImpl;

import mx.logging.ILogger;
	

public class DataVersionCheckerImpl implements IDataVersionChecker {
	
	private static const LOG: ILogger = Logger.getLog(DataVersionCheckerImpl);
	
	/** constructor jcinjected by spring */
	private var currentVersion: uint;
	
	/** injected by spring */
	public var persistenceService: IPersistenceService;
	
	private var versionFile: File = File.applicationStorageDirectory.resolvePath("data_version");
	
	private static const MIGRATORS: Array = [
		  MigrateFrom1To2
		// , MigrateFrom2To3
	];
	
	
	public function DataVersionCheckerImpl(currentVersion: uint) {
		this.currentVersion = currentVersion;
	}
	
	public function check(): void {
		if(this.persistenceService is MockPersistenceService) {
			LOG.info("Data version check skipped because using mock persistence service.");
			return;
		}
		LOG.info("Data version check invoked.");
		
		const installedVersion: uint = this.readInstalledVersion();
		
		if(installedVersion == this.currentVersion) {
			LOG.debug("Installed version [" + installedVersion + "] is up to date.");
			return;
		}
		
		// TODO show popup
		for(var i: int = installedVersion; i < this.currentVersion; i++) {
			LOG.info("Migrating data from version [" + i + "] to [" + this.currentVersion + "].");
			const migratorClass: Class = MIGRATORS[i-1] as Class;
			const migrator: IDataMigrator = new migratorClass();
			migrator.migrate((this.persistenceService as PersistenceServiceImpl).getConnection());
		}
		this.writeCurrentVersion();
	}
	
	private function readInstalledVersion(): uint {
		LOG.debug("Using version file at [" + this.versionFile.nativePath + "].");
		
		if(this.versionFile.exists == false) { // initial startup
			LOG.info("Version file does not exist.");
			this.writeCurrentVersion();
			return this.currentVersion;
		}
		
		const fs: FileStream = new FileStream();
		fs.open(this.versionFile, FileMode.READ);
		const installedVersion: int = fs.readInt();
		// const installedVersion: int = int(fs.readUTF());
		fs.close();
		
		LOG.debug("Read data version [" + installedVersion + "].");
		return installedVersion;
	}
	
	
	private function writeCurrentVersion(): void {
		LOG.debug("Writing current data version [" + this.currentVersion + "].");
		
		const fs: FileStream = new FileStream();
		fs.open(this.versionFile, FileMode.WRITE); // WRITE == create file if not existing; completly overrides content
		fs.writeInt(this.currentVersion);
		// fs.writeUTF(String(this.currentVersion));
		fs.close();
		
	}
}
}